<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <script>


        class myPromise {

            static PENDING = '待定';
            static FULFILLED = '成功';
            static REJECTED = '拒绝';
            constructor(func) {
                this.state = myPromise.PENDING;
                this.result = null;

                this.resolveCallbacks = [];
                this.rejectCallbacks = [];
                try {
                    func(this.resolve.bind(this), this.reject.bind(this));
                } catch (error) {
                    this.reject(error)
                }
            }
            resolve(result) {
                setTimeout(() => {
                    if (this.state === myPromise.PENDING) {
                        this.state = myPromise.FULFILLED;
                        this.result = result;
                        this.resolveCallbacks.forEach(callback => {
                            callback(result)
                        })
                    }
                })
            }
            reject(result) {
                setTimeout(() => {
                    if (this.state === myPromise.PENDING) {
                        this.state = myPromise.REJECTED;
                        this.result = result;
                        this.rejectCallbacks.forEach(callback => {
                            callback(result)
                        })
                    }
                })
            }
            then(onFULFILLED, onREJECTED) {


                return new myPromise((resolve, reject) => {
                    // 如果传入的参数不是函数
                    onFULFILLED = typeof onFULFILLED === "function" ? onFULFILLED : () => { }
                    onREJECTED = typeof onREJECTED === "function" ? onREJECTED : () => { }

                    if (this.state === myPromise.PENDING) {
                        this.resolveCallbacks.push(onFULFILLED);
                        this.rejectCallbacks.push(onREJECTED);
                    }

                    if (this.state === myPromise.FULFILLED) {
                        setTimeout(() => {
                            onFULFILLED(this.result)
                        })
                    }
                    if (this.state === myPromise.REJECTED) {
                        setTimeout(() => {
                            onREJECTED(this.result)
                        })
                    }

                })


            }

            static all(promises) {
                return new myPromise((resolve, reject) => {
                    if (!Array.isArray(promises)) {
                        throw new Error("参数应该为数组")
                    }
                    let len = promises.length;

                    if (len === 0) return resolve([]);
                    let fulfilledCount = 0;
                    let results = new Array(len);

                    promises.forEach((p, i) => {
                        let mp = p instanceof myPromise ? p : new myPromise((resolve, reject) => { resolve(p) });

                        mp.then(
                            data => {
                                results[i] = data;
                                fulfilledCount++;
                                if (fulfilledCount === len) resolve(results);
                            },
                            err => reject(err)
                        )
                    })

                })
            }


            static race(args) {
                return new myPromise((resolve, reject) => {
                    for (let i = 0, len = args.length; i < len; i++) {
                        args[i].then(resolve, reject)
                    }
                })
            }


        }



        // console.log("第一次")
        // let a = new myPromise((resolve, reject) => {
        //     console.log("第二次")
        //     setTimeout(() => {
        //         resolve("这次一定")
        //         reject("下次一定")
        //         console.log("第四次")
        //     })
        // })
        // a.then(
        //     data => {
        //         console.log(data)
        //     },
        //     err => {
        //         console.log(err.message)
        //     }
        // )
        // console.log("第三步")



        const p1 = new myPromise((resolve, reject) => resolve(1))
        const p2 = new myPromise(res => setTimeout(() => res(2), 500));
        const p3 = 3; // 非 Promise，应被自动包装

        myPromise.all([p1, p2, p3]).then(console.log); // [1, 2, 3]

        // 失败场景
        const p4 = new myPromise((res, rej) => setTimeout(() => rej('fail'), 300));
        myPromise.all([p1, p4, p3])
            .then(console.log)




    </script>
</body>

</html>